#Binary parser template

import os, sys
from Sanae3D.lib.StructReader import StructReader
from Sanae3D.lib.ModelObject import Model3D

class SevenSouls_BSB(Model3D):
    
    def __init__(self, obj3D=None, outFile=None, inFile=None):
        
        super(SevenSouls_BSB,self).__init__("XAC")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
    
    def read_name(self, term=0):
        
        charLen = self.inFile.read_long()
        name = self.inFile.read_string(charLen)
        if term:
            self.inFile.seek(1, 1)
        return name
    
    def parse_material(self):
        
        index = self.inFile.read_long()
        tex = self.read_name()
        mask = self.read_name()
        norm = self.read_name()
        #print tex
        #print mask
        #print norm
        
    def parse_unk1_section(self):
        
        unk = self.inFile.read_long()
        self.inFile.read_float(9)
        self.inFile.read_long()
        unkProp1 = self.read_name()
        print "unknown property: %s" %unkProp1
        
    def parse_vertices(self, meshName):
        
        numVerts = self.inFile.read_long()
        print "%d vertices" %numVerts, self.inFile.tell()
        for i in range(numVerts):
            vx, vy, vz = self.inFile.read_float(3)
            self.inFile.read_float(11)
            
            vx = float(vx) * -1
            
            self.create_vertex(meshName, i)
            self.add_coords(meshName, i, [vx, vy, vz])
            
    def parse_coords(self, numVerts, meshName):
        
        print "%d coords" %numVerts
        for i in range(numVerts):
            vx, vy, vz = self.inFile.read_float(3)
            vx = float(vx) * -1
            self.create_vertex(meshName, i)
            self.add_coords(meshName, i, [vx, vy, vz])
            
    def parse_indices(self, numFaces, meshName):
        
        print "%d faces" %numFaces
        for i in range(numFaces):
            v1, v2, v3 = self.inFile.read_short(3)
            self.create_face(meshName, i)
            self.add_face_verts(meshName, i, [v1, v2, v3])
            
    def parse_faces(self, meshName):
        
        sections = self.inFile.read_long()
        print "%d sections" %sections
        faceNum = 0
        for i in range(sections):
            numFaces = self.inFile.read_long()
            #print "%d faces" %numFaces
            for j in range(numFaces):
                v1, v2, v3 = self.inFile.read_short(3)
                
                self.create_face(meshName, faceNum)
                self.add_face_verts(meshName, faceNum, [v1, v2, v3])
                faceNum +=1
                
        
    def parse_mesh(self, meshNum):
        
        unk2 = 0
        if unk2 != 3:
            unk1 = self.inFile.read_long()
            print unk1
            self.inFile.read_long()
        meshName = self.read_name()
        self.create_object(meshName)
        if meshNum == 0:
            unkprop1 = self.read_name(1)
            unkprop2 = self.read_name()
        
        numFaces, numVerts = self.inFile.read_long(2)
        print "%s: %d faces, %d vertices" %(meshName, numFaces, numVerts), unk1
        
        if meshNum == 0:
            #self.inFile.read_long()
            self.inFile.read_long()
            self.inFile.read_byte()
            lightmap = self.read_name()
            #print lightmap
            self.inFile.read_byte()
            self.inFile.read_long()
            self.inFile.read_long()
            self.inFile.read_long()
            self.inFile.read_float(48) #16 * 3
            self.inFile.seek(41, 1) #???\
            self.parse_vertices(meshName)
            self.parse_faces(meshName)
            if unk1 == 1:
                self.inFile.seek(12, 1)
                unk2 = self.inFile.read_long()
            elif unk1 == 3:
                pass
        else:
            self.inFile.read_float(48)
            self.parse_coords(numVerts, meshName)
            self.parse_indices(numFaces, meshName)
        
    def parse_file(self):
        '''Main parser method. Can be replaced'''
        
        magic = self.inFile.read_string(4)
        unk1 = self.inFile.read_long()
        modelName = self.read_name()
        
        unk11 = self.inFile.read_long()
        unk12 = self.inFile.read_long()
        unk13 = self.inFile.read_long()
        unk14 = self.inFile.read_long()
        unk15 = self.inFile.read_long()
        unk16 = self.inFile.read_byte()
        unkProp1 = self.inFile.read_long()
        unk17 = self.inFile.read_long()
        self.inFile.read_float(9)
        
        #mat section
        numMat = self.inFile.read_long()
        
        print "%d materials" %numMat
        for i in range(numMat):
            self.parse_material()
            
        #unk section
        for i in range(unkProp1 - 1):
            self.parse_unk1_section()
        
        #mesh section
        numMesh = self.inFile.read_long()
        unk22 = self.inFile.read_long()
        unk23 = self.inFile.read_long()
        unk24 = self.inFile.read_long()
        unk25 = self.inFile.read_long()
        unk26 = self.inFile.read_long()
        numMesh2 = self.inFile.read_long()
        print "%d numMesh %d" %(numMesh, numMesh2)
        
        for i in range(numMesh):
            self.parse_mesh(i)
        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = SevenSouls_BSB(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

def definitions():
    '''Return the header, extension, and a description of the format'''
    
    return "BSOB", "BSB", "Seven Souls BSB"

if __name__ == '__main__':
    
    file1 = "archi_0364.bsb"
    file2 = "stone_0070.bsb"
    file3 = "prop_5045.bsb"
    obj = read_file(file3)
    